#include <cmath>
#include <wx/menu.h>
#include <wx/statline.h>
#include <wx/bitmap.h>
#include <wx/toolbar.h>
#include <wx/statline.h>
#include "wx/colordlg.h"

#include <iostream>

#include "mainFrame.h"
#include "myTreeItemData.h"

#include "../src/solid.h"

#include "../bitmaps/open.xpm"
#include "../bitmaps/save.xpm"
#include "../bitmaps/box.xpm"
#include "../bitmaps/corner.xpm"
#include "../bitmaps/sphere.xpm"
#include "../bitmaps/solids.xpm"
#include "../bitmaps/vertices.xpm"
#include "../bitmaps/edges.xpm"
#include "../bitmaps/faces.xpm"
#include "../bitmaps/wireframe.xpm"
#include "../bitmaps/control_points.xpm"
//#include "../bitmaps/quad.xpm"
//#include "../bitmaps/corner2d.xpm"
//#include "../bitmaps/circle.xpm"

#define MAX 50


BEGIN_EVENT_TABLE(MainFrame, wxFrame)
    EVT_MENU(wxID_OPEN, MainFrame::OnMenuFileOpen)
    EVT_MENU(wxID_SAVE, MainFrame::OnMenuFileSave)
    EVT_MENU(wxID_EXIT, MainFrame::OnMenuFileExit)
    EVT_MENU(wxID_HELP, MainFrame::OnMenuHelpAbout)
END_EVENT_TABLE()

MainFrame::MainFrame(const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame((wxFrame*) NULL, wxID_ANY, title, pos, size, style){
    createMenu();
    createCanvas();
    createPanel();
    createBar();

    sizer = new wxBoxSizer( wxHORIZONTAL );
    sizer->Add(panelTreeSizer, 1, wxALL|wxEXPAND, 0);
    sizer->Add(new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL ), 0, wxALL|wxEXPAND, 0 );
    sizer->Add(canvasSizer, 4, wxALL|wxEXPAND, 0);

    SetSizer( sizer );
    sizer->Fit(this);

    SetMinSize(wxSize(800,500));
}

MainFrame::~MainFrame(){
    delete glCanvas;
}

void MainFrame::createMenu(){
    // Make the "File" menu
    wxMenu *fileMenu = new wxMenu;
    fileMenu->Append(wxID_OPEN, wxT("Abrir\tCtrl+O"), wxT("Abrir arquivo"));
    fileMenu->Append(wxID_SAVE, wxT("&Salvar"), wxT("Salvar arquivo"));
    fileMenu->AppendSeparator();
    fileMenu->Append(wxID_EXIT, wxT("E&xit\tALT-X"), wxT("Sair do programa"));

    // Make the "Edit" menu
    wxMenu *editMenu = new wxMenu;
    editMenu->Append(SWEEP_MENU, wxT("Criar por varredura"), wxT("Desloca uma das faces de um solido"));
    editMenu->Append(BEZIER_MENU, wxT("Transformar em Bezier"), wxT("Transforma a face selecionada em bezier"));
    editMenu->Append(COLOR_MENU, wxT("Mudar a cor"), wxT("Muda a cor do solido selecionado"));

	this->Connect( SWEEP_MENU, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrame::sweepDialog ) );
	this->Connect( BEZIER_MENU, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrame::bezier ) );
	this->Connect( COLOR_MENU, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrame::changeColor ) );

    // Make the "Select" menu
    wxMenu *selectMenu = new wxMenu;
    selectMenu->Append(SELECT_FROM_TREE_MENU, wxT("Selecionar/deselecionar"), wxT("Selecionar/deselecionar da arvore"));

    wxMenu *selectAdjacentsMenu = new wxMenu;
    selectMenu->Append(SELECT_MENU, wxT("Adjacentes"), selectAdjacentsMenu);
    selectAdjacentsMenu->Append(SELECT_ADJACENT_VERTICES_MENU, wxT("Vertices"), wxT("Selecionar os vertices adjacentes"));
    selectAdjacentsMenu->Append(SELECT_ADJACENT_EDGES_MENU, wxT("Arestas"), wxT("Selecionar os arestas adjacentes"));
    selectAdjacentsMenu->Append(SELECT_ADJACENT_FACES_MENU, wxT("Faces"), wxT("Selecionar os faces adjacentes"));
    selectAdjacentsMenu->Append(SELECT_ADJACENT_SOLIDS_MENU, wxT("Solido"), wxT("Selecionar o solido adjacentes"));

	this->Connect( SELECT_FROM_TREE_MENU, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrame::selectFromTree ) );
	this->Connect( SELECT_ADJACENT_VERTICES_MENU, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrame::selectAdjacentVertices ) );
	this->Connect( SELECT_ADJACENT_EDGES_MENU, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrame::selectAdjacentEdges ) );
	this->Connect( SELECT_ADJACENT_FACES_MENU, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrame::selectAdjacentFaces ) );
	this->Connect( SELECT_ADJACENT_SOLIDS_MENU, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrame::selectAdjacentSolids ) );

    // Make the "Operators" menu
    wxMenu *operatorsMenu = new wxMenu;
    wxMenu *geometricMenu = new wxMenu;
    operatorsMenu->Append(wxID_ANY, wxT("Geometricos"), geometricMenu);
    geometricMenu->Append(TRANSLATE_OPERATOR_MENU, wxT("Translacao"), wxT("Fazer translacao no que esta selecionado"));
    geometricMenu->Append(SCALE_OPERATOR_MENU, wxT("Escala"), wxT("Fazer escala no que esta selecionado"));

	this->Connect( TRANSLATE_OPERATOR_MENU, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrame::translateDialog ) );
	this->Connect( SCALE_OPERATOR_MENU, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrame::scaleDialog ) );

    // Make the "Analyse" menu
    wxMenu *analyseMenu = new wxMenu;
    analyseMenu->Append(ANALYSE_AREA_MENU, wxT("Area"), wxT("Calculo da area do solido ou face selecionada"));

	this->Connect( ANALYSE_AREA_MENU, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrame::analyseArea ) );


    // Make the "Help" menu
    wxMenu *helpMenu = new wxMenu;
    helpMenu->Append(wxID_HELP, wxT("Sobre...\tCtrl+H"), wxT("Sobre o programa"));

    // Make the menu
    wxMenuBar *menuBar = new wxMenuBar;
    menuBar->Append(fileMenu, wxT("&Arquivo"));
    menuBar->Append(editMenu, wxT("&Edicao"));
    menuBar->Append(selectMenu, wxT("&Selecao"));
    menuBar->Append(operatorsMenu, wxT("&Operacoes"));
    menuBar->Append(analyseMenu, wxT("Ana&lise"));
    menuBar->Append(helpMenu, wxT("Aju&da"));
    SetMenuBar(menuBar);

    CreateStatusBar();
}

void MainFrame::createBar(){
    CreateToolBar(wxNO_BORDER | wxTB_FLAT | wxTB_HORIZONTAL);
    wxToolBar *toolBar = GetToolBar();

    wxBitmap bitmaps[11];

    //bitmaps[0] = wxBitmap( new_xpm );
    bitmaps[0] = wxBitmap( open_xpm );
    bitmaps[1] = wxBitmap( save_xpm );
    bitmaps[2] = wxBitmap( box_xpm );
    bitmaps[3] = wxBitmap( corner_xpm );
    bitmaps[4] = wxBitmap( sphere_xpm );
    bitmaps[5] = wxBitmap( solids_xpm );
    bitmaps[6] = wxBitmap( vertices_xpm );
    bitmaps[7] = wxBitmap( edges_xpm );
    bitmaps[8] = wxBitmap( faces_xpm );
    bitmaps[9] = wxBitmap( wireframe_xpm );
    bitmaps[10] = wxBitmap( control_points_xpm );
//    bitmaps[10] = wxBitmap( quad_xpm );
//    bitmaps[11] = wxBitmap( corner2d_xpm );
//    bitmaps[12] = wxBitmap( circle_xpm );



    toolBar->AddTool(wxID_OPEN, bitmaps[0], _T("Abrir"), _T("Abrir arquivo"));
    toolBar->AddTool(wxID_SAVE, bitmaps[1], _T("Salvar"), _T("Salvar arquivo"));
    toolBar->AddSeparator();
    toolBar->AddTool(ADD_BOX, bitmaps[2], _T("Adicionar cubo"), _T("Adicionar cubo no centro"));
    toolBar->AddTool(ADD_CORNER, bitmaps[3], _T("Adicionar canto"), _T("Adicionar canto"));
    toolBar->AddTool(ADD_SPHERE, bitmaps[4], _T("Adicionar esfera"), _T("Adicionar esfera"));
    toolBar->AddSeparator();

    toolBar->AddTool(SHOW_SOLIDS, wxEmptyString, bitmaps[5], wxNullBitmap, wxITEM_RADIO, _T("Mostrar solidos"), _T("Mostrar solidos da cena"));
    toolBar->AddTool(SHOW_VERTICES, wxEmptyString, bitmaps[6], wxNullBitmap, wxITEM_RADIO, _T("Realcar vertices"), _T("Realcar vertices do objeto selecionado"));
    toolBar->AddTool(SHOW_EDGES, wxEmptyString, bitmaps[7], wxNullBitmap, wxITEM_RADIO, _T("Realcar arestas"), _T("Realcar arestas do objeto selecionado"));
    toolBar->AddTool(SHOW_FACES, wxEmptyString, bitmaps[8], wxNullBitmap, wxITEM_RADIO, _T("Realcar faces"), _T("Realcar faces do objeto selecionado"));
    toolBar->AddTool(SHOW_WIREFRAME, wxEmptyString, bitmaps[9], wxNullBitmap, wxITEM_CHECK, _T("Wiretrame"), _T("Trocar entre wireframe e solido"));
    toolBar->AddTool(SHOW_CONTROL_POINTS, wxEmptyString, bitmaps[10], wxNullBitmap, wxITEM_CHECK, _T("Pontos de controle"), _T("Mostra os pontos de controle das superficies de beziers da face selecionada"));

//    this->Connect(ADD_QUAD, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler(MainFrame::addQuad));
//    this->Connect(ADD_CORNER2D, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler(MainFrame::addCorner2d));
//    this->Connect(ADD_CIRCLE, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler(MainFrame::addCircle));
    this->Connect(ADD_BOX, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler(MainFrame::addBox));
    this->Connect(ADD_CORNER, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler(MainFrame::addCorner));
    this->Connect(ADD_SPHERE, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler(MainFrame::addSphere));
    this->Connect(SHOW_SOLIDS, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler(MainFrame::setOptions));
    this->Connect(SHOW_VERTICES, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler(MainFrame::setOptions));
    this->Connect(SHOW_EDGES, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler(MainFrame::setOptions));
    this->Connect(SHOW_FACES, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler(MainFrame::setOptions));
    this->Connect(SHOW_WIREFRAME, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler(MainFrame::setOptions));
    this->Connect(SHOW_CONTROL_POINTS, wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler(MainFrame::setOptions));

    toolBar->Realize();
}

void MainFrame::createPanel(){
	wxPanel *panelTree = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
    panelTreeSizer = new wxBoxSizer( wxVERTICAL );
	panelTreeSizer->Add( panelTree, 1, wxEXPAND | wxALL, 3 );

	wxBoxSizer* treeSizer = new wxBoxSizer( wxVERTICAL );
	treeSolid = new MyTreeCtrl( panelTree, wxDefaultPosition, wxDefaultSize, /*wxTR_DEFAULT_STYLE */wxTR_MULTIPLE|wxTR_HAS_BUTTONS|wxTR_HIDE_ROOT );
	treeSizer->Add( treeSolid, 1, wxALL|wxEXPAND, 0 );

	treeSolid->Connect( wxEVT_COMMAND_TREE_ITEM_ACTIVATED, wxTreeEventHandler( MainFrame::treeDoubleClick ), NULL, this );
	//treeSolid->Connect( wxEVT_COMMAND_TREE_DELETE_ITEM, wxTreeEventHandler( MainFrame::treeDeleteItens ), NULL, this );
	treeSolid->Connect( wxEVT_COMMAND_TREE_KEY_DOWN, wxTreeEventHandler( MainFrame::OnTreeKeyDown ), NULL, this );

	panelTree->SetSizer( treeSizer );
	panelTree->Layout();
	treeSizer->Fit( panelTree );
}

void MainFrame::createCanvas(){
    // Make canvas
    canvasSizer = new wxBoxSizer( wxVERTICAL );
    glCanvas = new GLCanvas(this , wxID_ANY, wxDefaultPosition, wxDefaultSize);
    glCanvas->Refresh();
    canvasSizer->Add(glCanvas, 1, wxALL|wxEXPAND, 3);

}

void MainFrame::OnMenuFileOpen(wxCommandEvent& WXUNUSED(event)){
/*    wxString filename = wxFileSelector(wxT("Escolha o arquivo"), wxT(""), wxT(""), wxT(""),
    wxT("Geomod (*.gm)|*.gm"), wxFD_OPEN);

    if (!filename.IsEmpty()){
        glWindow->LoadFile(filename);
        glWindow->Refresh(false);
        glWindow->redoOctreeTreeCtrl(treeOctrees);


        treePrimitives->DeleteAllItems();
        treePrimitives->AddRoot(wxT("Objetos"));
        glWindow->primitivesReset();

        id = glWindow->octreesSize();

        chooseOctree1->Clear();
        chooseOctree2->Clear();
        chooseOctree3->Clear();
        wxString choice;
        for (unsigned int i = 0 ; i < id ; i++){
            choice = wxT("Octree ");
            choice += wxString::Format(wxT("%i"),i);
            chooseOctree1->Append(choice);
            chooseOctree2->Append(choice);
            chooseOctree3->Append(choice);
        }
        chooseOctree1->SetSelection( 0 );
        if (id > 1){
            chooseOctree2->SetSelection( 1 );
            opSetButton->Enable(true);
        }
        else chooseOctree2->SetSelection( 0 );
        chooseOctree3->SetSelection( 0 );
        chooseOctree1->Enable(true);
        chooseOctree2->Enable(true);
        chooseOctree3->Enable(true);
        opGeoButton->Enable(true);

        book->AdvanceSelection();

        octreeButton->SetLabel(_("Cancelar octree"));
        octreeButton->Enable(true);
        octreeButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::createOctree), NULL, this );
        octreeButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::cancelOctree ), NULL, this );
        octreeTreeButton->Enable(true);
//        octreeTreeButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::createOctreeTree), NULL, this );
//        octreeTreeButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::createOctreeTree ), NULL, this );

        id = 0;

    }*/
}

void MainFrame::OnMenuFileSave(wxCommandEvent& event){
/*    wxFileDialog filename(this, wxT("Escolha o arquivo"), wxT(""), wxT(""),
    wxT("Geomod (*.gm)"), wxFD_SAVE);///|wxFD_OVERWRITE_PROMPT);

    if (filename.ShowModal() == wxID_OK){
        wxTextCtrl *save = new wxTextCtrl(this, wxID_ANY, wxT(""));

        std::vector<std::string> treeSTDString = glWindow->getOctreesTree();

        int size = treeSTDString.size();
        wxString treeString, str, str2, dir = filename.GetDirectory(), name = filename.GetFilename();
        for (int i = 0; i < size; i++){
            treeString = wxString::FromAscii(treeSTDString[i].c_str());
            save->Clear();
            save->AppendText(treeString);

            str = dir;
            str += _("/");
            str += name;
            if (size == 1){
                    str += _(".gm");
            }
            else{
                str2.Printf(wxT("%d.gm"),i);
                str += str2;
            }

            if (save->SaveFile(str)){
                std::cout << "Salvando arquivo   " << str.mb_str() << std::endl;
            }
            else std::cout << "não salvou" << i<< std::endl;
        }

    }*/
}

void MainFrame::OnMenuFileExit(wxCommandEvent& event){
    Close(true);
}

void MainFrame::OnMenuHelpAbout(wxCommandEvent& WXUNUSED(event)){
    wxMessageBox(wxT("Trabalho 2 de Modelagem Geometrica 2009.2"));
}

//void MainFrame::addQuad(wxCommandEvent& event){
//    Solid *s = glCanvas->scene.makeQuad();
//    wxString str;
//    str.Printf(wxT("%d - Quadrado"), s->getID());
//    appendTreeItens(s, str);
//}
//
//void MainFrame::addCorner2d(wxCommandEvent& event){
//    Solid *s = glCanvas->scene.makeCorner2d();
//    wxString str;
//    str.Printf(wxT("%d - Canto 2D"), s->getID());
//    appendTreeItens(s, str);
//}
//
//void MainFrame::addCircle(wxCommandEvent& event){
//    Solid *s = glCanvas->scene.makeCircle();
//    wxString str;
//    str.Printf(wxT("%d - Circulo"), s->getID());
//    appendTreeItens(s, str);
//}

void MainFrame::addBox(wxCommandEvent& event){
    Solid *s = glCanvas->scene.makeBox();
    wxString str;
    str.Printf(wxT("%d - Cubo"), s->getID());
    appendTreeItens(s, str);
}

void MainFrame::addCorner(wxCommandEvent& event){
    Solid *s = glCanvas->scene.makeCorner();
    wxString str;
    str.Printf(wxT("%d - Canto"), s->getID());
    appendTreeItens(s, str);
}

void MainFrame::addSphere(wxCommandEvent& event){
    Solid *s = glCanvas->scene.makeSphere();
    wxString str;
    str.Printf(wxT("%d - Esfera"), s->getID());
    appendTreeItens(s, str);
}

void MainFrame::appendTreeItens(Solid *_s, wxString _str){
    wxTreeItemId solid = treeSolid->AppendItem(treeSolid->GetRootItem(), _str, 0, 0, new MyTreeItemData(_s));

    wxString str;
    wxTreeItemId faces = treeSolid->AppendItem(solid, wxT("Faces"));
    Face *f;
    for(int i = 0; i < _s->sizeFaces(); i++){
        f = _s->getFace(i);
        str.Printf(wxT("f%d"), f->getID() );
        treeSolid->AppendItem(faces, str, 0, 0, new MyTreeItemData(f));
    }

    wxTreeItemId edges = treeSolid->AppendItem(solid, wxT("Arestas"));
    Edge *e;
    for(int i = 0; i < _s->sizeEdges(); i++){
        e = _s->getEdge(i);
        str.Printf(wxT("e%d"), e->getID() );
        treeSolid->AppendItem(edges, str, 0, 0, new MyTreeItemData(e));
    }

    wxTreeItemId vertices = treeSolid->AppendItem(solid, wxT("Vertices"));
    Vertex *v;
    for(int i = 0; i < _s->sizeVertices(); i++){
        v = _s->getVertix(i);
        str.Printf(wxT("v%d (%1.2f, %1.2f, %1.2f)"), v->getID(), v->getPoint().x, v->getPoint().y, v->getPoint().z );
        treeSolid->AppendItem(vertices, str, 0, 0, new MyTreeItemData(v));
    }

    //treeSolid->Expand(treeSolid->GetRootItem());
    glCanvas->Refresh();
}

void MainFrame::OnTreeKeyDown( wxTreeEvent& event ){
    long key = event.GetKeyCode();

    if((key == WXK_DELETE)){
        treeDeleteItens();
    }

    Refresh();
}

void MainFrame::treeDoubleClick(wxTreeEvent& event){
    treeSolid->selectItens(&glCanvas->scene);
    glCanvas->Refresh();
}

void MainFrame::treeDeleteItens(){
    bool ok = treeSolid->deleteItens(&glCanvas->scene);

    if (!ok){
        wxMessageBox(wxT("Escolha somente solidos."), _("Erro"), wxICON_ERROR);
    }
    glCanvas->Refresh();
}

void MainFrame::selectFromTree(wxCommandEvent& event){
    treeSolid->selectItens(&glCanvas->scene);
    glCanvas->Refresh();
}

void MainFrame::selectAdjacentVertices(wxCommandEvent& event){
    treeSolid->selectAdjacentVertices(&glCanvas->scene);
    glCanvas->Refresh();
}

void MainFrame::selectAdjacentEdges(wxCommandEvent& event){
    treeSolid->selectAdjacentEdges(&glCanvas->scene);
    glCanvas->Refresh();
}

void MainFrame::selectAdjacentFaces(wxCommandEvent& event){
    treeSolid->selectAdjacentFaces(&glCanvas->scene);
    glCanvas->Refresh();
}

void MainFrame::selectAdjacentSolids(wxCommandEvent& event){
    treeSolid->selectAdjacentSolids(&glCanvas->scene);
    glCanvas->Refresh();
}

void MainFrame::scaleDialog(wxCommandEvent& event){
    wxDialog dlg(this, wxID_ANY, _T("Escala"), wxDefaultPosition, wxSize(190,80));

    wxPanel* sacalePanel = new wxPanel(&dlg, wxID_ANY);

	wxBoxSizer* topSizer = new wxBoxSizer( wxVERTICAL );

    //dados do lambda
	wxBoxSizer* lambdaSizer = new wxBoxSizer ( wxHORIZONTAL );
	lambdaSizer->Add( new wxStaticText ( sacalePanel, wxID_ANY, wxT("Lambda:"), wxDefaultPosition, wxDefaultSize, 0 ), 0, wxALL, 9 );
	lambdaSpinBox = new wxSpinCtrl( sacalePanel, ID_SPINCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, -MAX, MAX, 2 );
	lambdaSizer->Add( lambdaSpinBox, 0, wxALL, 3 );

	topSizer->Add( lambdaSizer, 1, wxEXPAND, 3 );

	wxStdDialogButtonSizer* buttonsSizer = new wxStdDialogButtonSizer();
	wxButton* buttonOK = new wxButton( sacalePanel, wxID_OK );
	buttonOK->SetDefault();
	buttonsSizer->AddButton( buttonOK  );
	wxButton* buttonCancel = new wxButton( sacalePanel, wxID_CANCEL );
	buttonsSizer->AddButton( buttonCancel );
	buttonsSizer->Realize();
	topSizer->Add( buttonsSizer, 1, wxEXPAND, 3 );

	buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::scale ), NULL, this );

    sacalePanel->SetSizer( topSizer );
    topSizer->Fit(sacalePanel);

    dlg.CentreOnParent();
    dlg.ShowModal();
}

void MainFrame::scale(wxCommandEvent& event){
    glCanvas->scene.scale(lambdaSpinBox->GetValue());
    treeSolid->repopulate(&glCanvas->scene, false);
    glCanvas->Refresh();
    event.Skip();
}

void MainFrame::translateDialog(wxCommandEvent& event){
    wxDialog dlg(this, wxID_ANY, _T("Translacao"), wxDefaultPosition, wxSize(410,80));

    wxPanel* translatePanel = new wxPanel(&dlg, wxID_ANY);

	wxBoxSizer* topSizer = new wxBoxSizer( wxVERTICAL);
	wxBoxSizer* optionsSizer = new wxBoxSizer ( wxHORIZONTAL );

    //dados da translacao no x
	optionsSizer->Add( new wxStaticText ( translatePanel, wxID_ANY, wxT("X:"), wxDefaultPosition, wxDefaultSize, 0 ), 0, wxALL, 9 );
	xSpinBox = new wxSpinCtrl( translatePanel, ID_SPINCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, -MAX, MAX, 1 );
	optionsSizer->Add( xSpinBox, 0, wxALL, 3 );

    //dados da translacao no y
	optionsSizer->Add( new wxStaticText ( translatePanel, wxID_ANY, wxT("  Y:"), wxDefaultPosition, wxDefaultSize, 0 ), 0, wxALL, 9 );
	ySpinBox = new wxSpinCtrl( translatePanel, ID_SPINCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, -MAX, MAX, 0 );
	optionsSizer->Add( ySpinBox, 0, wxALL, 3 );

    //dados da translacao no z
	optionsSizer->Add( new wxStaticText ( translatePanel, wxID_ANY, wxT("  Z:"), wxDefaultPosition, wxDefaultSize, 0 ), 0, wxALL, 9 );
	zSpinBox = new wxSpinCtrl( translatePanel, ID_SPINCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, -MAX, MAX, 0 );
	optionsSizer->Add( zSpinBox, 0, wxALL, 3 );

	topSizer->Add( optionsSizer, 1, wxEXPAND, 3 );

	wxStdDialogButtonSizer* buttonsSizer = new wxStdDialogButtonSizer();
	wxButton* buttonOK = new wxButton( translatePanel, wxID_OK );
	buttonOK->SetDefault();
	buttonsSizer->AddButton( buttonOK  );
	wxButton* buttonCancel = new wxButton( translatePanel, wxID_CANCEL );
	buttonsSizer->AddButton( buttonCancel );
	buttonsSizer->Realize();
	topSizer->Add( buttonsSizer, 1, wxEXPAND, 3 );

	buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::translate ), NULL, this );

    translatePanel->SetSizer( topSizer );
    topSizer->Fit(translatePanel);

    dlg.CentreOnParent();
    dlg.ShowModal();
}

void MainFrame::translate(wxCommandEvent& event){
    glCanvas->scene.translate( Point(xSpinBox->GetValue(), ySpinBox->GetValue(), zSpinBox->GetValue()) );
    treeSolid->repopulate(&glCanvas->scene, false);
    glCanvas->Refresh();
    event.Skip();
}

void MainFrame::analyseArea(wxCommandEvent& event){
    double area = 0;
    bool ok = glCanvas->scene.analyseArea(&area);
    if (ok){
        wxString str = _("Area de ");
        str += wxString::Format(wxT("%1.2f"), area);
        wxMessageBox(str, _("Area"), wxOK);
    }
    else{
        wxMessageBox(wxT("Escolha somente faces ou solidos."), _("Erro"), wxICON_ERROR);
    }
}

void MainFrame::sweepDialog(wxCommandEvent& event){
    wxDialog dlg(this, wxID_ANY, _T("Varredura"), wxDefaultPosition, wxSize(410,80));

    wxPanel* sweepPanel = new wxPanel(&dlg, wxID_ANY);

	wxBoxSizer* topSizer = new wxBoxSizer( wxVERTICAL);
	wxBoxSizer* optionsSizer = new wxBoxSizer ( wxHORIZONTAL );

    //dados da translacao no x
	optionsSizer->Add( new wxStaticText ( sweepPanel, wxID_ANY, wxT("X:"), wxDefaultPosition, wxDefaultSize, 0 ), 0, wxALL, 9 );
	xSpinBox = new wxSpinCtrl( sweepPanel, ID_SPINCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, -MAX, MAX, 1 );
	optionsSizer->Add( xSpinBox, 0, wxALL, 3 );

    //dados da translacao no y
	optionsSizer->Add( new wxStaticText ( sweepPanel, wxID_ANY, wxT("  Y:"), wxDefaultPosition, wxDefaultSize, 0 ), 0, wxALL, 9 );
	ySpinBox = new wxSpinCtrl( sweepPanel, ID_SPINCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, -MAX, MAX, 1 );
	optionsSizer->Add( ySpinBox, 0, wxALL, 3 );

    //dados da translacao no z
	optionsSizer->Add( new wxStaticText ( sweepPanel, wxID_ANY, wxT("  Z:"), wxDefaultPosition, wxDefaultSize, 0 ), 0, wxALL, 9 );
	zSpinBox = new wxSpinCtrl( sweepPanel, ID_SPINCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, -MAX, MAX, 0 );
	optionsSizer->Add( zSpinBox, 0, wxALL, 3 );

	topSizer->Add( optionsSizer, 1, wxEXPAND, 3 );

	wxStdDialogButtonSizer* buttonsSizer = new wxStdDialogButtonSizer();
	wxButton* buttonOK = new wxButton( sweepPanel, wxID_OK );
	buttonOK->SetDefault();
	buttonsSizer->AddButton( buttonOK  );
	wxButton* buttonCancel = new wxButton( sweepPanel, wxID_CANCEL );
	buttonsSizer->AddButton( buttonCancel );
	buttonsSizer->Realize();
	topSizer->Add( buttonsSizer, 1, wxEXPAND, 3 );

	buttonOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::sweep ), NULL, this );

    sweepPanel->SetSizer( topSizer );
    topSizer->Fit(sweepPanel);

    dlg.CentreOnParent();
    dlg.ShowModal();
}

void MainFrame::sweep(wxCommandEvent& event){
    bool ok = glCanvas->scene.sweep( Point(xSpinBox->GetValue(), ySpinBox->GetValue(), zSpinBox->GetValue()) );
    if (!ok){
        wxMessageBox(wxT("Escolha somente uma face."), _("Erro"), wxICON_ERROR);
    }
    treeSolid->repopulate(&glCanvas->scene, false);
    glCanvas->Refresh();
    event.Skip();
}

void MainFrame::bezier(wxCommandEvent& event){
    bool ok = glCanvas->scene.toBezier();
    if (!ok){
        wxMessageBox(wxT("Escolha somente uma face."), _("Erro"), wxICON_ERROR);
    }
    treeSolid->repopulate(&glCanvas->scene, false);
    glCanvas->Refresh();
    event.Skip();
}

void MainFrame::changeColor(wxCommandEvent& event){
    Color color;
    wxColourData colorData;
    wxColourDialog dialog(this, &colorData);
    dialog.SetTitle(_T("Escolha a cor"));
    if (dialog.ShowModal() == wxID_OK){
        colorData = dialog.GetColourData();
        int red = colorData.GetColour().Red();
        int green = colorData.GetColour().Green();
        int blue = colorData.GetColour().Blue();

        color = Color(red/255., green/255., blue/255.);
    }


    bool ok = glCanvas->scene.changeColor(color);
    if (!ok){
        wxMessageBox(wxT("Escolha somente um solido."), _("Erro"), wxICON_ERROR);
    }
    glCanvas->Refresh();
    event.Skip();
}

void MainFrame::setOptions(wxCommandEvent& event){
    switch(event.GetId()){
        case SHOW_SOLIDS:
            glCanvas->setHighligtOption(0);
            break;

        case SHOW_VERTICES:
            glCanvas->setHighligtOption(1);
            break;

        case SHOW_EDGES:
            glCanvas->setHighligtOption(2);
            break;

        case SHOW_FACES:
            glCanvas->setHighligtOption(3);
            break;

        case SHOW_WIREFRAME:
            if (event.IsChecked()) glCanvas->setWireframeOption(true);
            else  glCanvas->setWireframeOption(false);
            break;

        case SHOW_CONTROL_POINTS:
            if (event.IsChecked()) glCanvas->setControlPointsOption(true);
            else  glCanvas->setControlPointsOption(false);
            break;
    }
    glCanvas->Refresh();
}
